package cn.b.sky.mes.pp.controller;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import cn.b.sky.mes.pp.enums.OrderStatusCode;
import cn.b.sky.mes.pp.model.OrderType;
import cn.b.sky.mes.pp.model.ProductionOrder;
import cn.b.sky.mes.pp.model.ProductionOrderPlan;
import cn.b.sky.mes.pp.model.condition.ProductionOrderCondition;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;

import cn.b.sky.mes.cm.model.CalendarDay;
import cn.b.sky.mes.cm.model.StandardCapacity;
import cn.b.sky.mes.cm.model.WorkCenterCalendarDay;
import cn.b.sky.mes.cm.model.WorkDayPeriod;
import cn.b.sky.mes.cm.service.CalendarService;
import cn.b.sky.mes.cm.service.StandardCapacityService;
import cn.b.sky.mes.cm.service.WorkCenterService;
import cn.b.sky.mes.cm.service.WorkDayTypeService;
import cn.b.sky.common.model.DWZResult;
import cn.b.sky.common.model.Page;
import cn.b.sky.user.SecurityContextUtil;
import cn.b.sky.user.controller.SecurityController;
import cn.b.sky.mes.cm.enums.ECodeEnums;
import cn.b.sky.user.service.ECodeService;
import cn.b.sky.user.service.model.ECode;
import cn.b.sky.mes.pp.service.OrderTypeService;
import cn.b.sky.mes.pp.service.ProductionOrderPlanService;
import cn.b.sky.mes.pp.service.ProductionOrderService;

/**
 * 
 * <strong>Title : ProductionOrderArrangementController.java<br>
 * </strong> <strong>Package : cn.b.sky.mes.pp.controller<br>
 * </strong> <strong>Description : </strong>生产订单排产控制器<br>
 * <strong>Create on : 2016年1月15日 下午2:30:03<br>
 * </strong>
 * <p>
 * 
 * @author dapeng.li<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 *          <strong>修改历史:</strong><br>
 *          修改人 | 修改日期 | 修改描述<br>
 *          -------------------------------------------<br>
 * <br>
 * <br>
 */
@Controller
@RequestMapping(value = "/productionOrderArrangement/*")
public class ProductionOrderArrangementController extends SecurityController {

  private static final String UNCOMPLETED_ORDER_ARRANGEMENT_LIST = "pp/orderArrangement/uncompletedOrder_list";

  private static final String ORDER_ARRANGEMENT_LIST = "pp/orderArrangement/orderArrangement_list";

  @Autowired
  ProductionOrderService orderService;

  @Autowired
  WorkCenterService workCenterService;

  @Autowired
  OrderTypeService orderTypeService;

  @Autowired
  ECodeService eCodeService;

  @Autowired
  ProductionOrderPlanService orderPlanService;

  @Autowired
  CalendarService calendarService;

  @Autowired
  WorkDayTypeService workDayTypeService;

  @Autowired
  StandardCapacityService standardCapacityService;

  @RequestMapping("getProductionOrderStatus")
  @ResponseBody
  public DWZResult getProductionOrderStatus() {
    List<ECode> eCodes = eCodeService.selectECodeList(ECodeEnums.PRODUCTIONORDER_TYPE.getCode(),
        SecurityContextUtil.getLanguageCode());
    return ajaxDone(eCodes);
  }

  /**
   * 
   * <strong>Title : orderSchedulePage<br></strong>
   * <strong>Description : </strong>订单排产界面入口<br> 
   * <strong>Create on : 2016年7月29日 上午10:41:46<br></strong>
   * <p>
   * @param navTabId
   * @param model
   * @param startDate
   * @param endDate
   * @param orderType
   * @return
   * String
   * @throws 
   * @author dapeng.li<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("unarrangedOrder_list_page")
  public String orderSchedulePage(String navTabId, Model model, String startDate, String endDate, String orderType) {
    prepareArrangementPageModel(navTabId, model, startDate, endDate, orderType);
    return UNCOMPLETED_ORDER_ARRANGEMENT_LIST;
  }

  /**
   * 
   * <strong>Title : operationSchedulePage<br></strong>
   * <strong>Description : </strong>工序排产界面入口<br> 
   * <strong>Create on : 2016年7月29日 上午10:42:05<br></strong>
   * <p>
   * @param navTabId
   * @param model
   * @param startDate
   * @param endDate
   * @param orderType
   * @return
   * String
   * @throws 
   * @author dapeng.li<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("unarrangedOrder_list_page/operation")
  public String operationSchedulePage(String navTabId, Model model, String startDate, String endDate,
      String orderType) {
    prepareArrangementPageModel(navTabId, model, startDate, endDate, orderType);
    model.addAttribute("operationScheduleFlag", 1);
    return UNCOMPLETED_ORDER_ARRANGEMENT_LIST;
  }

  private void prepareArrangementPageModel(String navTabId, Model model, String startDate, String endDate,
      String orderType) {
    List<OrderType> orderTypes = orderTypeService.getAllOrderTypes(this.getSiteCode());
    List<ECode> eCodes = eCodeService.selectECodeList(ECodeEnums.PRODUCTIONORDER_TYPE.getCode(),
        SecurityContextUtil.getLanguageCode());
    model.addAttribute("orderTypes", JSON.toJSONString(orderTypes));
    model.addAttribute("eCodes", JSON.toJSONString(eCodes));
    model.addAttribute("scheduleDays", orderPlanService.selectScheduleDays());
    bindModelAttributs(model, navTabId, startDate, endDate, orderType);
  }

  @RequestMapping("getUncompletedOrdersByCondition")
  @ResponseBody
  public DWZResult getUncompletedOrdersByCondition(ProductionOrderCondition condition) {
    if (StringUtils.isEmpty(condition.getSiteCode())) {
      condition.setSiteCode(getSiteCode());
    }
    Page page = orderService.getUncompletedOrdersByCondition(condition);
    return ajaxDone(page);
  }

  @RequestMapping("orderArrangement_list_page")
  public String orderArrangementListPage(String navTabId, String startDate, String endDate, String orderNums,
      Model model, String orderType) {
    model.addAttribute("orderNums", orderNums);
    bindModelAttributs(model, navTabId, startDate, endDate, orderType);
    return ORDER_ARRANGEMENT_LIST;
  }

  private void bindModelAttributs(Model model, String navTabId, String startDate, String endDate, String orderType) {
    model.addAttribute(NAVTABID, navTabId);
    model.addAttribute("startDate", startDate);
    model.addAttribute("endDate", endDate);
    model.addAttribute("orderType", orderType);
  }

  @RequestMapping("loadWorkCenters")
  @ResponseBody
  public DWZResult loadWorkCenters() {
    return ajaxDone(workCenterService.getAllWorkCenterListBySiteCode(getSiteCode(), 0));
  }

  @RequestMapping("loadWorkCenterData")
  @ResponseBody
  public DWZResult loadWorkCenterData(String workCenterCode, String startDate, String endDate) {
    Map<String, Object> map = new HashMap<String, Object>();
    setWorkCenterData(map, workCenterCode, startDate, endDate);
    return ajaxDone(map);
  }

  private void setWorkCenterData(Map<String, Object> map, String workCenterCode, String startDate, String endDate) {
    // 组装工作中心日历相关数据
    Map<String, List<CalendarDay>> calendarDaysMap = new HashMap<String, List<CalendarDay>>();
    String[] workCenterCodes = null;
    if (!StringUtils.isEmpty(workCenterCode)) {
      workCenterCodes = new String[] { workCenterCode };
    }
    List<WorkCenterCalendarDay> workcenterCalendarDays = calendarService.selectWorkCenterCalendarDays(getSiteCode(),
        workCenterCodes, startDate, endDate);
    for (WorkCenterCalendarDay calendarDay : workcenterCalendarDays) {
      if (!calendarDaysMap.containsKey(calendarDay.getWorkCenterCode())) {
        calendarDaysMap.put(calendarDay.getWorkCenterCode(), calendarDay.getCalendarDays());
      }
    }
    map.put("calendarDaysMap", calendarDaysMap);

    // 组装日历类型的工作时段数据
    Map<String, List<WorkDayPeriod>> workDayPeriodsMap = new HashMap<String, List<WorkDayPeriod>>();
    List<WorkDayPeriod> workDayPeriods = workDayTypeService.selectWorkDayPeriods(getSiteCode());
    for (WorkDayPeriod workDayPeriod : workDayPeriods) {
      if (!workDayPeriodsMap.keySet().contains(workDayPeriod.getDayTypeCode())) {
        workDayPeriodsMap.put(workDayPeriod.getDayTypeCode(), new LinkedList<WorkDayPeriod>());
      }
      workDayPeriodsMap.get(workDayPeriod.getDayTypeCode()).add(workDayPeriod);
    }
    map.put("workDayPeriodsMap", workDayPeriodsMap);

    // 组装工作中心的产能数据
    Map<String, List<StandardCapacity>> capacitiesMap = new HashMap<String, List<StandardCapacity>>();
    List<StandardCapacity> capacities = standardCapacityService.selectAllStandardCapacityList(getSiteCode(),
        workCenterCode);
    for (StandardCapacity standardCapacity : capacities) {
      if (!capacitiesMap.containsKey(standardCapacity.getWorkCenterCode())) {
        capacitiesMap.put(standardCapacity.getWorkCenterCode(), new LinkedList<StandardCapacity>());
      }
      capacitiesMap.get(standardCapacity.getWorkCenterCode()).add(standardCapacity);
    }
    map.put("capacitiesMap", capacitiesMap);
  }

  @RequestMapping("getUncompletedOrdersByOrderNums")
  @ResponseBody
  public DWZResult getUncompletedOrdersByOrderNums(HttpServletRequest request, String orderNums, String startDate,
      String endDate) {
    Map<String, Object> map = new HashMap<String, Object>();

    // 查询时间段内已经排产的生产订单计划
    List<ProductionOrderPlan> orderPlans = orderPlanService.selectProductionOrderPlansByDate(orderNums.split(","),
        getSiteCode(), SecurityContextUtil.getLanguageCode(), startDate, endDate);
    map.put("orderPlans", orderPlans);

    // 已经排产过的生产订单
    List<ProductionOrderPlan> arrangedOrders = orderPlanService.selectArrangedOrdersByOrderNums(getSiteCode(),
        orderNums.split(","), SecurityContextUtil.getLanguageCode());
    Set<String> arrangedOrderNums = new HashSet<String>();
    for (ProductionOrderPlan order : arrangedOrders) {
      arrangedOrderNums.add(order.getProductionOrderNum());
    }
    map.put("arrangedOrders", arrangedOrders);

    // 没有完工的生产订单（筛除已经排产过的生产订单）
    List<ProductionOrderPlan> uncompletedOrders = orderPlanService
        .selectUncompletedOrdersByOrderNums(orderNums.split(","), getSiteCode(), SecurityContextUtil.getLanguageCode());
    Iterator<ProductionOrderPlan> orderIterator = uncompletedOrders.iterator();
    while (orderIterator.hasNext()) {
      ProductionOrderPlan order = orderIterator.next();
      if (arrangedOrderNums.contains(order.getProductionOrderNum())) {
        orderIterator.remove();
      }
    }
    map.put("uncompletedOrders", uncompletedOrders);

    return ajaxDone(map);
  }

  @RequestMapping("saveOrderPlanListAndIssueOrder")
  @ResponseBody
  public DWZResult saveOrderPlanListAndIssueOrder(String orderPlans, String orderNums, String arrangedOrderNums,
      String startDate, String orderDetailQuantity) {
    List<ProductionOrderPlan> orderPlanObjs = JSONArray.parseArray(orderPlans, ProductionOrderPlan.class);
    @SuppressWarnings("unchecked")
    Map<String, Map<String, Integer>> map = JSON.parseObject(orderDetailQuantity, Map.class);
    for (String orderNum : map.keySet()) {
      ProductionOrder order = orderService.getProductionOrderByPk(getSiteCode(), orderNum);
      if (null == order) {
        continue;
      }
      // 更新订单状态
      order.setStatuseCode(OrderStatusCode.PLACE_ORDER.getValue());
      // 更新修改信息
      setModifyInfo(order);
      // 是否保存订单的新状态
    }
    for (String orderNum : orderNums.split(",")) {
      orderPlanService.deleteOrderPlanByOrderNumAndStartDate(getSiteCode(), orderNum, startDate);
    }
    for (ProductionOrderPlan orderPlan : orderPlanObjs) {
      if (null == orderPlan.getSiteCode()) {
        orderPlan.setSiteCode(getSiteCode());
      }
      setCreateInfo(orderPlan);
      orderPlanService.saveOrderPlan(orderPlan);
    }
    return ajaxDone(null);
  }

  @RequestMapping("releaseIssuedOrders")
  @ResponseBody
  public DWZResult releaseIssuedOrders(String orderNums) {
    for (String orderNum : orderNums.split(",")) {
      ProductionOrder order = orderService.getProductionOrderByPk(getSiteCode(), orderNum);
      if (null != order && order.getStatuseCode().equals(OrderStatusCode.PLACE_ORDER.getValue())) {
        orderPlanService.deleteOrderPlanByOrderNum(getSiteCode(), orderNum);
        orderService.modifyIssuedProductionOrder(orderNum, getSiteCode());
      }
    }
    return ajaxDone(null);
  }
}
